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的person
public void delete(Integer personid) ;
//删除指定id的person,flag
public 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("dele