赞
踩
Spring中最常用的事务管理器是DataSourceTransactionManager
配置事务管理器
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
Java Config方式配置事务
@Configuration
@ComponentScan(basePackages = "com.spring.transaction.*")
@EnableTransactionManagement
public class JavaConfig implements TransactionManagementConfigurer {
private DataSource dataSource = null;
@Bean(name = "dataSource")
public DataSource initDataSource() {
if (dataSource != null)
return dataSource;
Properties props = new Properties();
props.setProperty("driverClassName", "com.mysql.jdbc.Driver");
props.setProperty("url", "jdbc:mysql://localhost:3306/weixin");
props.setProperty("username", "root");
props.setProperty("password", "root");
props.setProperty("maxActive", "200");
props.setProperty("maxIdle", "20");
props.setProperty("maxWait", "30000");
try {
dataSource = BasicDataSourceFactory.createDataSource(props);
} catch (Exception e) {
e.printStackTrace();
}
return dataSource;
}
@Bean(name = "jdbcTemplate")
public JdbcTemplate initJdbcTemplate() {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(initDataSource());
return jdbcTemplate;
}
@Override
@Bean(name = "transactionManager")
public PlatformTransactionManager annotationDrivenTransactionManager() {
DataSourceTransactionManager transactionManager =
new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
使用注解@EnableTransactionManagement后,在Spring上下文中使用事务注解@Transactional,这样Spring就知道使用该数据库事务管理器管理事务了。
编程式事务
public static void main(String[] args) {
/*编程式事务(不推荐使用)*/
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext("applicationContext-dao.xml");
JdbcTemplate jdbcTemplate = ctx.getBean(JdbcTemplate.class);
TransactionDefinition def = new DefaultTransactionDefinition();
PlatformTransactionManager transactionManager =
ctx.getBean(PlatformTransactionManager.class);
TransactionStatus status = transactionManager.getTransaction(def);
try {
jdbcTemplate.update("insert into t_lecture(lecture_name, note) " +
"values ('Python', 'Xixi')");
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
e.printStackTrace();
}
}
声明式事务(一种约定型的事务)
<!--配置使用@Transactional配置事务-->
<tx:annotation-driven transaction-manager="transactionManager"/>
XML方式配置事务管理器
<!--配置事务拦截器-->
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager"/>
<!--Spring IoC启动时会解析这些内容,放到事务定义类TransactionDefinition中,运行时根据正则匹配程度决定采取的策略-->
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED, ISOLATION_READ_UNCOMMITTED</prop>
<prop key="save*">PROPAGATION_REQUIRED, ISOLATION_READ_UNCOMMITTED</prop>
<prop key="add*">PROPAGATION_REQUIRED, ISOLATION_READ_UNCOMMITTED</prop>
<prop key="select*">PROPAGATION_REQUIRED, readOnly</prop>
<prop key="get*">PROPAGATION_REQUIRED, readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED, readOnly</prop>
<prop key="del*">PROPAGATION_REQUIRED, ISOLATION_READ_UNCOMMITTED</prop>
<prop key="remove*">PROPAGATION_REQUIRED, ISOLATION_READ_UNCOMMITTED</prop>
<prop key="update*">PROPAGATION_REQUIRED, ISOLATION_READ_UNCOMMITTED</prop>
</props>
</property>
</bean>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!--指定拦截哪些类-->
<property name="beanNames">
<list>
<value>*ServiceImpl</value>
</list>
</property>
<!--定义事务拦截器-->
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
在ServiceImpl上使用注解定义事务属性
public class RoleServiceImpl implements IRoleService {
@Override
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT
, timeout = 3)
public int insertRole(Role role) {
// 执行业务逻辑...
return 0;
}
}
@Transaction的底层实现是基于AOP,而AOP又是基于动态代理的,所以对于静态方法和非public方法,@Transaction是失效的。
在动态代理中,被代理对象调用了自身的其他方法,而该方法又被@Transaction标注,此时@Transaction失效。因为在方法内部调用是不会调用代理对象的。解决方法就是从Spring IoC容器中获取对象(代理对象)。
事务的使用注意:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。