问题描述
- 求大神帮忙 spring aop 方式事务不回滚怎么搞?
-
spring 版本 4.1.7代码如下:
表:
CREATE TABLEusers
(id
int(11) unsigned NOT NULL AUTO_INCREMENT,nick_name
varchar(100) DEFAULT NULL,password
varchar(100) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;INSERT INTO
users
VALUES ('1', 'Jennifer', 'Alice');
INSERT INTOusers
VALUES ('2', '爱', '克斯莱');java 文件:
1)
package com.maxwell.spring.jdbc.tx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.maxwell.spring.jdbc.vo.User;@Service
public class UserAopService
{@Autowired private UserDao dao; public UserAopService() {} /** * 此处的@Transactional注解把这个方法中的所有数据库操作当作事务进行处理 */ public void testTransactionManager() { String nn = dao.addUser(new User().setNickName("Jensen").setPassword("jensen")); int i = dao.getIdByNickName(nn); System.out.println(i); dao.setNickNameById(i, "Nimei"); }
}
2)
package com.maxwell.spring.jdbc.tx;import java.util.HashMap;
import java.util.List;
import java.util.Map;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;import com.maxwell.spring.jdbc.vo.User;
/**
- 用于测试事务
- @author Techwork
*
*/
@Repository
public class UserDao {@Autowired
@Qualifier("npJdbcTpl")
private NamedParameterJdbcTemplate jdbcTpl;public String addUser(User user) {
String sql = "INSERT INTO users (nick_name, password) VALUES (:nickName, :password)";SqlParameterSource paramSource = new BeanPropertySqlParameterSource(user); jdbcTpl.update(sql, paramSource); return user.getNickName();
}
public int getIdByNickName(String nickName) {
String sql = "select id, nick_name, password from users where nick_name = :xxx"; Map<String, Object> paramMap = new HashMap<>(); paramMap.put("xxx", nickName); RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class); List<User> users = jdbcTpl.query(sql, paramMap, rowMapper); if(users == null || users.size() < 1) { throw new RuntimeException("无此用户:" + nickName); } return users.get(0).getId();
}
public void setNickNameById(int id, String nickName) {
if(nickName.length() < 10) throw new RuntimeException("性别错误"); String sql = "update users set nick_name = :n where id = :i"; Map<String, Object> paramMap = new HashMap<>(); paramMap.put("n", nickName); paramMap.put("i", id); jdbcTpl.update(sql, paramMap);
}
}
3)
package com.maxwell.spring.jdbc.tx;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;import com.maxwell.spring.jdbc.vo.User;
@Service
public class UserService
{@Autowired private UserDao dao; public UserService() {} /** * 此处的@Transactional注解把这个方法中的所有数据库操作当作事务进行处理 */ @Transactional public void testTransactionManager() { String nn = dao.addUser(new User().setNickName("Jensen").setPassword("jensen")); int i = dao.getIdByNickName(nn); System.out.println(i); dao.setNickNameById(i, "Nimei"); } /** * propagation: 指定事务的传播行为 * isolation: 指定事务的隔离级别 * noRollbackFor: 指定对哪些异常不回滚。通常取默认值。 * rollbackFor: 指定对哪些异常回滚。通常取默认值。 * readOnly: 只读事务。如果事务只读取数据,而不写数据的话,设置为true,有助于数据库引擎优化事务。 * timeout: 指定强制回滚事务(就算可能成功)之前,事务可以存在的时间,以防止事务占用数据库连接时间过长。 */ @Transactional(isolation = Isolation.READ_COMMITTED, noRollbackFor = { Exception.class }, rollbackFor = { RuntimeException.class }, readOnly = true, timeout = 3) public void testTransactionManager2() { String nn = dao.addUser(new User().setNickName("Jensen").setPassword("jensen")); int i = dao.getIdByNickName(nn); dao.setNickNameById(i, "哈哈"); }
}
4)
package com.maxwell.spring.jdbc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.maxwell.spring.jdbc.tx.UserAopService;
/**
- 测试AOP事务
- @author Angrynut
- */
public class AOPTransactionTest
{
private ApplicationContext ctx = null;
private UserAopService service = null;{
ctx = new ClassPathXmlApplicationContext("aoptx.xml");
service = ctx.getBean("userAopService", UserAopService.class);
}/**
- 1.测试AOP事务。
*/
@Test
public void testTransactionManager()
{
service.testTransactionManager();
}
- 1.测试AOP事务。
}
spring 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd"><context:component-scan base-package="com.maxwell.spring.jdbc"/> <!-- 数据源配置文件 --> <util:properties id="db" location="classpath:db.properties"/> <!-- 配置C3p0数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="#{db['jdbc.user']}"/> <property name="password" value="#{db['jdbc.password']}"/> <property name="driverClass" value="#{db['jdbc.driverClass']}"/> <property name="jdbcUrl" value="#{db['jdbc.jdbcUrl']}"/> <property name="initialPoolSize" value="#{db['jdbc.initPoolSize']}"/> <property name="maxPoolSize" value="#{db['jdbc.maxPoolSize']}"/> </bean> <bean id="npJdbcTpl" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"> <constructor-arg ref="dataSource"/> </bean> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution(* com.maxwell.spring.jdbc.tx.UserService.*(..))" id="pc"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/> </aop:config>
解决方案
看到 抛出了运行时异常,而且你在事务里给出 在运行时异常 去回滚 ,你再看下 ,我明天测一下