摘自:http://zhxing.iteye.com/blog/368110
|
事务传播行为类型 |
说明 |
|
PROPAGATION_REQUIRED |
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。 |
|
PROPAGATION_SUPPORTS |
支持当前事务,如果当前没有事务,就以非事务方式执行。如果是在事务中调用的,则加入事务中. |
|
PROPAGATION_MANDATORY |
使用当前的事务,如果当前没有事务,就抛出异常。 |
|
PROPAGATION_REQUIRES_NEW |
新建事务,如果当前存在事务,把当前事务挂起。即不论是否存在事务,业务方法都会为自己发起一个事务. |
|
PROPAGATION_NOT_SUPPORTED |
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
|
PROPAGATION_NEVER |
以非事务方式执行,如果当前存在事务,则抛出异常。 |
|
PROPAGATION_NESTED |
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。 |
当使用PROPAGATION_NESTED时,底层的数据源必须基于JDBC 3.0,并且实现者需要支持保存点事务机制。
1. 更新丢失(Lost update):两个事务都同时更新一行数据但是第二个事务却中途失败退出导致对数据两个修改都失效了这是系统没有执行任何锁操作因此并发事务并没有被隔离开来。
隔离级别 更新丢失 脏读取 重复读取 幻读
未授权读取 N Y Y Y
授权读取 N N Y Y
可重复读取 N N N Y
串行 N N N N
import java.util.List;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class UserDaoImpl implements UserDao {
//private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
//this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
@Transactional(rollbackFor=Exception.class)//碰到Exception类的异常则进行回滚
//@Transactional(noRollbackFor=RuntimeException.class)//对运行时异常则是不回滚
public void delete(int id) {
jdbcTemplate.update("delete from User where id = ?",
new Object[]{id},new int[]{java.sql.Types.INTEGER});
}
@Override
//内嵌事务不会影响外面事务的提交与回滚
//@Transactional(propagation=Propagation.NOT_SUPPORTED)/propagation设置事务传播行为,这里设置其不支持事务,如此则在方法执行前则不会开启事务
@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true,timeout=30)//设置只读事务,超时时间,默认30秒
public List<User> getAllUser() {
return (List<User>)jdbcTemplate.queryForObject("select * from User", new UserRowMapper());
}
@Override
@Transactional(propagation=Propagation.NOT_SUPPORTED,
readOnly=true,timeout=30)
//设置只读事务,超时时间,默认30秒
public User getUser(int id) {
return (User)jdbcTemplate.queryForObject("select * from User",new Object[]{id},new int[]{java.sql.Types.INTEGER}
,new UserRowMapper());
}
@Override
public void save(User user) {
jdbcTemplate.update("insert into User(name) values(?)",
new Object[]{user.getName()},new int[]{java.sql.Types.VARCHAR});
}
@Override
public void update(User user) {
jdbcTemplate.update("update User set name = ? where id = ? ",
new Object[]{user.getName(),user.getId()},new int[]{java.sql.Types.VARCHAR,java.sql.Types.INTEGER});
}
}
XML式:<bean id="dataSource" class="" destroy-method=""> <property name="driverClassName" value="org.gjt.mm.mysql.Driver"> </property> <property name="url" value="jdbc:mysql://localhost:3301/SpringJDBC"></property> <property name="username" value="root"></property> <property name="password" value="126"></property> <property name="initialSize" value="1"></property> <property name="maxActive" value="100"></property> <property name="maxIdle" value="2"></property> <property name="minIdle" value="1"></property> </bean> <!-- 事务管理器 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <aop:config> <!-- 定义拦截点 --> <aop:pointcut id="transactionPointCut" expression="execution(* com.spring305.jdbc.test.po.UserDaoImpl2(..))" /> <!-- 通知 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointCut"/> </aop:config> <!-- 设置事务行为 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/> <tx:method name="list*" read-only="true" /> <tx:method name="query*" read-only="true" /> <tx:method name="find*" read-only="true" /> <tx:method name="*" /> </tx:attributes> </tx:advice>
本文详细介绍了事务的传播行为类型及其应用场景,包括REQUIRED、SUPPORTS、MANDATORY等,并解释了事务隔离级别的概念及其实现机制,如未授权读取、授权读取、可重复读取和串行等。
904

被折叠的 条评论
为什么被折叠?



