在前面的“Spring学习_04_Spring和Hibernate整合数据源(DataSource)”一文中,我们没有指定我们事务的属性,现在我们为其加上我们事务的属性。更改我们service的代码如下:
@Transactional(propagation=Propagation.REQUIRED,readOnly=false)
public void add(User user) {
userDAO.save(user);
addMsg();
}
@Transactional(propagation=Propagation.MANDATORY,readOnly=false)
public void addMsg(){
Msg msg = new Msg();
msg.setLog("a user saved!");
msgDao.save(msg);
}
这里我们将前面的方法add拆分成了两部分,这样做的用意是测试使用的传播属性(propagation)。
事物的传播属性有以下几个取值(很重要,尤其是REQUIRED。要理解什么事事务的传播特性)(来自于spring文档):
Enum Constant Summary | |
---|---|
MANDATORY Support a current transaction, throw an exception if none exists. | |
NESTED Execute within a nested transaction if a current transaction exists, behave like PROPAGATION_REQUIRED else. | |
NEVER Execute non-transactionally, throw an exception if a transaction exists. | |
NOT_SUPPORTED Execute non-transactionally, suspend the current transaction if one exists. | |
REQUIRED Support a current transaction, create a new one if none exists. | |
REQUIRES_NEW Create a new transaction, suspend the current transaction if one exists. | |
SUPPORTS Support a current transaction, execute non-transactionally if none exists. |
另外属性是readonly,如果在这里设置为true,表明在事务所在的方法中只会对数据库做只读操作,凡是涉及到insert,update,delete的方法都不会允许执行。所以上面如果我们在add和addMsg方法中我们设置readonly=true的话,则往数据库中插入数据的时候,就会报错。这个属性完全是spring用来对数据库操作进行优化的,通俗来说就是readonly对应的Connection的效率要比readwrite的Connection的效率要高很多。
isolation:事物的隔离级别,这个和Hibernate中完全一样。
timeout:设置事物的超时时长是多少。
rollbackfor:指出发生那种异常的时候,会造成事务回滚,这个默认是发生RuntimeException。一般事务运行的时候发生运行时异常回滚就是在这里设置的,其他几个属性同样道理,不做细说。