spring事务

事务的特性

  • 原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
  • 一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
  • 隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
  • 持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。

   在企业级应用程序开发中,事务管理必不可少的技术,用来确保数据的完整性和一致性。

 

Spring事务的配置方式

 

1. 编程式事务管理

编程式事务管理是侵入性事务管理,使用TransactionTemplate或者直接使用PlatformTransactionManager,对于编程式事务管理,Spring推荐使用TransactionTemplate。

使用方式1

//开启事务保存数据
boolean result = transactionTemplate.execute(new TransactionCallback<Boolean>() {
    @Override
    public Boolean doInTransaction(TransactionStatus status) {
        try {
            // TODO something
        } catch (Exception e) {
            //TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动开启事务回滚
            status.setRollbackOnly();
            logger.error(e.getMessage(), e);
            return false;
        }
        return true;
    }
});

 

使用方式2

/**
 * 定义事务
 */
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setReadOnly(false);
//隔离级别,-1表示使用数据库默认级别
def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);
try {
    //TODO something
     transactionManager.commit(status);
} catch (Exception e) {
    transactionManager.rollback(status);
    throw new InvoiceApplyException("异常失败");
}

 

 使用方式3,这里没有使用TransactionTemplate

SqlSession sqlSession = null;
try {
    sqlSession = otInvSqlSessionFactory.openSession(ExecutorType.BATCH, true);
    XXXXXMapper xXxxMapper = sqlSession.getMapper(XXXXXMapper.class);
    sqlSession.commit();
}catch(Exception e){
    if (null != otInvSqlSession) {
        sqlSession.rollback(true);
        logger.error("数据回滚", e);
    }
}finally {
    if (null != sqlSession) {
        sqlSession.clearCache();
        sqlSession.close();
    }
}

 

2. 声明式事务管理

声明式事务管理建立在AOP之上,其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,执行完目标方法之后根据执行的情况提交或者回滚。
编程式事务每次实现都要单独实现,但业务量大功能复杂时,使用编程式事务无疑是痛苦的,而声明式事务不同,声明式事务属于无侵入式,不会影响业务逻辑的实现,只需要在配置文件中做相关的事务规则声明或者通过注解的方式,便可以将事务规则应用到业务逻辑中。
显然声明式事务管理要优于编程式事务管理,这正是Spring倡导的非侵入式的编程方式。唯一不足的地方就是声明式事务管理的粒度是方法级别,而编程式事务管理是可以到代码块的,但是可以通过提取方法的方式完成声明式事务管理的配置。

package cn.itcast.service;

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cn.itcast.dao.OrdersDao;

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false, timeout = -1)
public class OrdersService {
    private OrdersDao ordersDao;

    public void setOrdersDao(OrdersDao ordersDao) {
        this.ordersDao = ordersDao;
    }

    // 调用dao的方法
    // 业务逻辑,写转账业务
    public void accountMoney() {
        // 小马多1000
        ordersDao.addMoney();
        // 加入出现异常如下面int i=10/0(银行中可能为突然停电等。。。);结果:小马账户多了1000而小王账户没有少钱
        // 解决办法是出现异常后进行事务回滚
        // int i = 10 / 0;// 事务管理配置后异常已经解决
        // 小王 少1000
        ordersDao.reduceMoney();
    }
}

 

配置文件

    <!-- 配置c3po连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- 注入属性值 -->
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/wangyiyun"></property>
        <property name="user" value="root"></property>
        <property name="password" value="153963"></property>
    </bean>
    <!-- 第一步:配置事务管理器 (和配置文件方式一样)-->
    <bean id="dataSourceTransactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 注入dataSource -->
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 第二步: 开启事务注解 -->
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager" />
    <!-- 第三步 在方法所在类上加注解 -->


    <!-- 对象生成及属性注入 -->
    <bean id="ordersService" class="cn.itcast.service.OrdersService">
        <property name="ordersDao" ref="ordersDao"></property>
    </bean>
    <bean id="ordersDao" class="cn.itcast.dao.OrdersDao">
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>
    </bean>
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

 

Spring声明式事务配置参考

事物配置中有哪些属性可以配置?以下只是简单的使用参考

  1. 事务的传播性:
    @Transactional(propagation=Propagation.REQUIRED)
  2. 事务的隔离级别:
    @Transactional(isolation = Isolation.READ_UNCOMMITTED)

读取未提交数据(会出现脏读, 不可重复读) 基本不使用

  1. 只读:
    @Transactional(readOnly=true)
    该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。
  2. 事务的超时性:
    @Transactional(timeout=30)
  3. 回滚:
    指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)
    指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值