当前位置: 代码迷 >> J2EE >> Spring 的transaction 注解事务 传播性和隔离性的有关问题
  详细解决方案

Spring 的transaction 注解事务 传播性和隔离性的有关问题

热度:81   发布时间:2016-04-22 01:34:04.0
Spring 的transaction 注解事务 传播性和隔离性的问题
Java code
        @Autowired    ITestDAO dao ;//设置timeout 2秒 超时就报异常  @Transactional(timeout=2,rollbackFor=Exception.class)    public int save(Test t) throws Exception {        System.out.println("进入**");        for (int i = 0; i < 500000; i++) {            System.out.println("*");        }                System.out.println("进入保存");        dao.save(t);//数据库插入操作        System.out.println("退出保存");         }



我设置了事务超时,但是为什么超时后 异常显示了,但是数据也插入却没用回滚?


spring中的timeout是默认为-1 就是永远不超时。但是我设置了2秒。 (for 循环50W 有2秒时间吧?) 异常报出来
但是hibernate在控制台也打印出sql语句 并且插入进去数据了。这并不是我预期的结果。
应该是异常后 回滚了。所以想请教下:

这个timeout并不是我能设置出来的时间吗?
最近看这方面的知识,事务传播性和隔离性。

为了防止脏读和重复读、幻读 
(isolation)的隔离级别我只能使用串行化?

事务的传播性也正在努力测试中、

------解决方案--------------------
timeout应该是对应的connection的超时吧
System.out.println("进入保存");
dao.save(t);//数据库插入操作
throw new Exception();
System.out.println("退出保存");

这样就可以测试了,如果数据插进去了,说明你的事务配置不正确,事务并没有开启
------解决方案--------------------
默认遇到throw new RuntimeException("...");会回滚
需要捕获的throw new Exception("...");不会回滚

// 指定回滚
@Transactional(rollbackFor=Exception.class) 
public void methodName() {
// 不会回滚
throw new Exception("...");

//指定不回滚
@Transactional(noRollbackFor=Exception.class)
public ItimDaoImpl getItemDaoImpl() {
// 会回滚
throw new RuntimeException("注释");


// 如果有事务,那么加入事务,没有的话新建一个(不写的情况下)
@Transactional(propagation=Propagation.REQUIRED) 
// 容器不为这个方法开启事务
@Transactional(propagation=Propagation.NOT_SUPPORTED)
// 不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
@Transactional(propagation=Propagation.REQUIRES_NEW) 
// 必须在一个已有的事务中执行,否则抛出异常
@Transactional(propagation=Propagation.MANDATORY)
// 必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)
@Transactional(propagation=Propagation.NEVER) 
// 如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.
@Transactional(propagation=Propagation.SUPPORTS) 

 
@Transactional(propagation=Propagation.NESTED) 
// readOnly=true只读,不能更新,删除 
@Transactional (propagation = Propagation.REQUIRED,readOnly=true) 
// 设置超时时间
@Transactional (propagation = Propagation.REQUIRED,timeout=30)
// 设置数据库隔离级别
@Transactional (propagation = Propagation.REQUIRED,isolation=Isolation.DEFAULT)
------解决方案--------------------
你是基于注解的配置。
@Transactional 注解应该只被应用到 public 可见度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会展示已配置的事务设置。
默认的 @Transactional 设置如下:
事务传播设置是 PROPAGATION_REQUIRED
事务隔离级别是 ISOLATION_DEFAULT
事务是 读/写
事务超时默认是依赖于事务系统的,或者事务超时没有被支持。
任何 RuntimeException 将触发事务回滚,但是任何 checked Exception 将不触发事务回滚,需要我们在外部用try/catch语法对调用该方法的地方进行包含 @Transactional,也就是在方法级别加如类似于@Transactional(rollbackFor=Exception.class)
在同一个类中一个方法调用另一个有事务的方法,事务是不会起作用的。
Java code
public interface PersonService {//删除指定id的personpublic void delete(Integer personid) ;//删除指定id的person,flagpublic void delete(Integer personid,boolean flag) ;}public class PersonServiceBean implements PersonService {private JdbcTemplate jdbcTemplate;public void delete(Integer personid){try{this.delete(personid,true)System.out.println("delete success");}catch(Exception e){System.out.println("delete failed");}}
  相关解决方案