当前位置:首页 > spring trascation
1Spring事务传播行为
所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。Spring支持7种事务传播行为
PROPAGATION_REQUIRED(加入已有事务)
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见也是默认的方式。
PROPAGATION_SUPPORTS(跟随环境)
支持当前事务,如果当前没有事务,就以非事务方式执行。 PROPAGATION_MANDATORY(需要事务) 使用当前的事务,如果当前没有事务,就抛出异常。 PROPAGATION_REQUIRES_NEW(独立事务) 新建事务,如果当前存在事务,把当前事务挂起。 PROPAGATION_NOT_SUPPORTED(非事务方式)
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 PROPAGATION_NEVER(排除事务)
以非事务方式执行,如果当前存在事务,则抛出异常。 PROPAGATION_NESTED(嵌套事务)
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
Spring默认的事务传播行为是PROPAGATION_REQUIRED,它适合于绝大多数的情况。假设ServiveX#methodX()都工作在事务环境下(即都被Spring事务增强了),假设程序中存在如下的调用链:
Service1#method1()->Service2#method2()->Service3#method3(),那么这3个服务类的3个方法通过Spring的事务传播机制都工作在同一个事务中。 如果在一个ServiceA和a()方法中启动一个线程,在这个新创建的线程中执行ServiceB的事务方法b()。在相同线程中进行相互嵌套调用的事务方法工作于相同的事务中。如果这些相互嵌套调用的方法工作在不同的线程中,不同线程下的事务方法工作在独立的事务中。
2多种数据持久方法事务管理
如果你采用了一个高端ORM技术(Hibernate,JPA,JDO),同时采用一个JDBC技术(Spring JDBC,iBatis),由于前者的会话(Session)是对后者连接(Connection)的封装,Spring会“足够智能地”在同一个事务线程让前者的会话封装后者的连接。所以,我们只要直接采用前者的事务管理器就可以了。下表给出了混合数据访问技术所对应的事务管理器:
1不同持久方式的事务统一
Spring提供了一个能从当前事务上下文中获取绑定的数据连接的工具类,那就是DataSourceUtils。Spring强调必须使用DataSourceUtils工具类获取数据连接。 static Connection doGetConnection(DataSource dataSource) 首先尝试从事务上下文中获取连接,失败后再从数据源获取连接; static Connection getConnection(DataSource dataSource)
doGetConnection方法的功能一样,实际上,它内部就是调用doGetConnection方法获取连接的;
static void doReleaseConnection(Connection con, DataSource dataSource) 释放连接,放回到连接池中;
static void release Connection(Connection con, DataSource dataSource) 和doReleaseConnection方法的功能一样,实际上,它内部就是调用doReleaseConnection方法获取连接的; 测试demo: ?
1 2 3 4 5 6 7 8 9 10 11 12 @Service
public class TestTranscationServiceImpl implements TestTranscationService {
@Autowired
private TestTranscationDao testTranscationDao;
@Override
@Transactional public int test(){
testTranscationDao.update1();
testTranscationDao.update2(); return 0;
13 } 14 } ? 1 @Autowired 2 private JdbcTemplate jdbcTemplate; 3
4 @Override
5 public int update1() { 6 //1.获得数据库连接
7 Connection con = DataSourceUtils.getConnection(jdbcTemplate.getDataSource()8 try {
9 con.prepareStatement(\10 } catch (SQLException e) { 11 throw new RuntimeException(e); 12 }finally { 13 //2如果当前方法没有上下文事务管理,不释放数据库连接会造成数据库连接泄露14 //如果存在上下文事务,调用或者不调用数据库连接释放都没有问题 15 DataSourceUtils.releaseConnection(con, jdbcTemplate.getDataSource()); 16 } 17 return 0; 18 19 } 20 21 @Override 22 public int update2(){ 23 //3.获得数据库连接 和1的数据库连接是同一个连接 24 Connection con = DataSourceUtils.getConnection(jdbcTemplate.getDataSource()25 try { 26 //4.这种方法取到的数据库连接和 1,3取到的数据库连接不同 27 Connection conn = jdbcTemplate.getDataSource().getConnection(); 28 conn.close(); 29 } catch (SQLException e) { 30 e.printStackTrace(); 31 } 32 return jdbcTemplate.update(\高中三年级' w33 }
Spring为每个数据访问技术框架都提供了一个获取事务上下文绑定的数据连接(或其衍生品)的工具类和数据源(或其衍生品)的代理类。
共分享92篇相关文档