gpt4 book ai didi

java - 为什么我的事务没有被 Spring 注解回滚?

转载 作者:行者123 更新时间:2023-11-29 20:57:45 26 4
gpt4 key购买 nike

我束手无策,试图调试这个问题。基本上,我有一个 mvc 应用程序,其中有一个 BusinessManagerImpl 类,该类有 2 个 DAO(UserDaoProductDao),并且正在使用带有连接的 JDBC池而不是 ORM。数据库是带有InnoDb引擎的mySQL。 RestUserControllerBusinessManagerImpl的调用类。

BusinessManagerImpl.addUser() 已使用 @Transactional 注释进行注释。我还尝试在类级别注释 @Transactional 但似乎没有什么区别。两个 DAO 也都有这样的注释。

BusinessManagerImpl.addUser() 使用 UserDao 插入用户,但随后调用 ProductDao.getAllProducts() 会抛出 RuntimeException 故意导致事务回滚。我的期望是,用户不应该被插入,因为发生了 RuntimeException,并且事务将被回滚,但我已经检查了我的数据库并插入了新用户。

我尝试抛出已检查的异常并使用@Transactional注释的“rollback for”参数,但它不起作用。我还尝试了不同的传播值,例如 Propagation.Required 但似乎对回滚事务没有影响。我尝试在 stackoverflow 和 google 上搜索,但没有找到任何有帮助的信息。有人可以阐明我做错了什么或遗漏了什么吗?谢谢。以下是我的设置:

应用程序上下文.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<context:component-scan base-package="someproject" />
<!-- <context:annotation-config /> -->


<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/somedb" />
<property name="username" value="xxx" />
<property name="password" value="yyy" />
</bean>

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>

BusinessManagerImpl 类

@Service 
public class BusinessManagerImpl implements BusinessManager{

@Autowired
private UserDao userDao;

@Autowired
private ProductDao productDao;
....
@Override
@Transactional(propagation=Propagation.REQUIRED)
public User addUser(User user) throws Exception {
// TODO Auto-generated method stub
User tempUser = userDao.addUser(user);
productDao.getAllProducts();

return tempUser;
}

UserDaoImpl 类

@Service
public class UserDaoImpl implements UserDao {

private DataSource dataSource;

@Autowired
public UserDaoImpl(DataSource dataSource) {
super();
setDataSource(dataSource);
}

public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}

private JdbcTemplate getJdbcTemplate(){
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

return jdbcTemplate;
}
...
@Override
@Transactional(propagation=Propagation.MANDATORY)
public User addUser(final User user) {
KeyHolder holder = new GeneratedKeyHolder();

final String sql = "insert into user (username, password) "
+ " VALUES (?, ?)";

getJdbcTemplate().update(new PreparedStatementCreator() {

@Override
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(sql.toString(), Statement.RETURN_GENERATED_KEYS);

int index = 1;

ps.setString(index++, user.getUsername());
ps.setString(index++, user.getPassword());


return ps;
}
}, holder);

int seq = holder.getKey().intValue();
user.setSeq(seq);
return user;
}

ProductDaoImpl 类

@Service
public class ProductDaoImpl implements ProductDao {

private DataSource dataSource;

@Autowired
public ProductDaoImpl(DataSource dataSource) {
super();
setDataSource(dataSource);
}

public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}

@Override
@Transactional(propagation=Propagation.MANDATORY)
public List<Product> getAllProducts() throws Exception {

if(true)
throw new RuntimeException("on purpose");

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
List<Product> products = jdbcTemplate.query(
"select * from product",
new ProductRowMapper());

return products;
}

RestUserController 类

@RestController
public class RestUserController {
private static Logger logger = LoggerFactory.getLogger(RestUserController.class);

@Autowired
private BusinessManager businessManager;

@RequestMapping(value = "/adduser", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> createEmployee(@RequestBody User user)
{
logger.debug("adding user:"+user);
User addedUser=null;
try {
addedUser = businessManager.addUser(user);
return new ResponseEntity(addedUser, HttpStatus.CREATED);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);

}

web.xml

   <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>Spring3 MVC Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/application-context.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>spring-web</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-web</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

spring-web-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">

<context:component-scan base-package="someproject" />

<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>

<mvc:resources mapping="/resources/**" location="/resources/" />

<mvc:annotation-driven />

</beans>

最佳答案

我发现在 Dao 实现类上使用 @Service 注释很奇怪。尝试用 @Repository 替换它们,并将 rollbackFor = {Exception.class} 添加到所有事务注释中。

关于java - 为什么我的事务没有被 Spring 注解回滚?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37496395/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com