我正在使用spring 3.0.5版本。我只是做简单的测试程序来测试事务的行为但没有得到。我编写了三层架构项目。其中dao层包含以下代码行。
@Repository("commonDao")
@Transactional
public class CommonDaoImpl implements CommonDao {
private static Logger logger = Logger.getLogger(CommonDaoImpl.class);
@Autowired
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
@Autowired
public void setSessionFactory(){
jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public Object makePayment(Object e) {
String sql = "insert into payment (id, name, amount) values('abc', 100)";
return new NullPointerException();
}
@Override
public Object signUp(Object e) {
String sql = "insert into login (userid, password) values('naveen', 'password')";
return jdbcTemplate.update(sql);
}
}
服务层看起来像这样。
@Service
public class CommonServiceImpl implements CommonService {
private static Logger logger = Logger.getLogger(CommonServiceImpl.class);
@Autowired
private CommonDao commonDao;
// I tried both of them one by one but not worked
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
@Override
public boolean makePayment(HttpServletRequest request) {
WebApplicationContext ctxt = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
commonDao.signUp(new Object());
commonDao.makePayment(new Object());
return true;
}
}
控制器看起来像这样
@RequestMapping("/doPayment")
public void doPayment(HttpServletRequest request){
logger.info("controller");
WebApplicationContext ctxt = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
commonService.makePayment(request);
}
dispatcher-servlet.xml文件
<context:component-scan base-package="com" />
<!-- <context:annotation-config /> -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="password" />
</bean>
<!-- Add this tag to enable annotations transactions -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
web.xml文件包含
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
它非常简单的程序。在哪个服务层调用dao注册和makePayment两种方法下的事务。注册方法成功执行但makePayment抛出异常。现在问题是因为两个方法在事务下执行所以不会对数据库进行操作。但是在登录表中插入数据而支付表是空的。但根据我对事务的理解,不应将任何条目插入数据库。有人可以帮助我做些什么。
Invoking request handler method: public void com.controller.CommonController.doPayment(javax.servlet.http.HttpServletRequest)
controller
Using transaction object [org.springframework.jdbc.datasource.DataSourceTransactionManager$DataSourceTransactionObject@1b7379b]
Creating new transaction with name [com.service.CommonService.makePayment]: PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT,-throwable
Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/test]
Acquired Connection [com.mysql.jdbc.JDBC4Connection@74b8d3] for JDBC transaction
Switching JDBC Connection [com.mysql.jdbc.JDBC4Connection@74b8d3] to manual commit
Bound value [org.springframework.jdbc.datasource.ConnectionHolder@6a56c0] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@25a0f5] to thread [http-bio-8080-exec-14]
Initializing transaction synchronization
Getting transaction for [com.service.CommonService.makePayment]
Executing SQL update [insert into login (userid, password) values('naveen', 'password')]
Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@6a56c0] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@25a0f5] bound to thread [http-bio-8080-exec-14]
Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@6a56c0] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@25a0f5] bound to thread [http-bio-8080-exec-14]
SQL update affected 1 rows
Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@6a56c0] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@25a0f5] bound to thread [http-bio-8080-exec-14]
Completing transaction for [com.service.CommonService.makePayment]
Triggering beforeCommit synchronization
Triggering beforeCompletion synchronization
Initiating transaction commit
Committing JDBC transaction on Connection [com.mysql.jdbc.JDBC4Connection@74b8d3]
Triggering afterCommit synchronization
Triggering afterCompletion synchronization
Clearing transaction synchronization
Removed value [org.springframework.jdbc.datasource.ConnectionHolder@6a56c0] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@25a0f5] from thread [http-bio-8080-exec-14]
Releasing JDBC Connection [com.mysql.jdbc.JDBC4Connection@74b8d3] after transaction
Returning JDBC Connection to DataSource
Invoking afterPropertiesSet() on bean with name 'action/doPayment'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Rendering view [org.springframework.web.servlet.view.InternalResourceView: name 'action/doPayment'; URL [/WEB-INF/pages/action/doPayment.jsp]] in DispatcherServlet with name 'dispatcher'
Forwarding to resource [/WEB-INF/pages/action/doPayment.jsp] in InternalResourceView 'action/doPayment'
Successfully completed request
当我看到日志文件时,它正在使用事务实例。可以帮助解决这个问题。