我的一个项目:maven多模块,springboot启动
在启动类加上了@EnableTransactionManagement注解,
@SpringBootApplication
@EnableTransactionManagement
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
项目中引入了spring-boot-data-jpa
springboot中引入下面任何一个依赖,会自动实现springboot的事务管理,除非人为指定事务管理
jdbc:
pom.xml ——>spring-boot-starter-jdbc 使用它提供的模板方法
连接数据库注入的是——>JdbcTemplate
jpa: java persisitence api java持久化API
pom.xml ——>spring-boot-starter-data-jpa
连接数据库注入的是——>继承了jpaRepository接口的接口UserDAO,除了提供默认实现,还可按照一定规则自定义方法名,或者自己写sql
另外自定义连接sql,使用mybatis时,springboot也进行了整合:
mybatis:
pom.xml----->mybatis-spring-boot-starter
关于如何整合使用jdbc和jpa可以参考一下博客:
https://blog.csdn.net/qq_28332595/article/details/88537789
我这里没有主动做事务配置,虽然引入了spring-boot-data-jpa,但是并没有使用这中Repository接口继承的方式实现sql
所以在启动springboot时,会有以下提示(不影响启动springboot,但是为后面的注解的使用留下了隐患)
PostProcessorRegistrationDelegate$BeanPostProcessorChecker (PostProcessorRegistrationDelegate.java:330) - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$883a5c7c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
启动类上
下面在service的实现类上加上@Transactional
去掉jdbc,jpa后,在在数据源xml中增加配置
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<context:annotation-config />
在spring-boot启动时报错
The bean 'org.springframework.transaction.config.internalTransactionAdvisor', defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class], could not be registered. A bean with that name has already been defined in null and overriding is disabled.
后在application.xml中增加配置
spring.main.allow-bean-definition-overriding=true
启动成功
但是事务还是不起作用
修改扫描包这里,还是不起作用
<context:component-scan base-package="com.atzy.wm.service;">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
如果不在xml中配置事务管理器,而是引入spring-boot-starter-jdbc
则启动ok,在运行带有注解Transactional的service方法时,报错
No qualifying bean of type 'org.springframework.transaction.PlatformTransactionManager' available
未开启事务时打印语句如:
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@66d01651] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@39512118 wrapping com.mysql.cj.jdbc.ConnectionImpl@7ba30dd3] will not be managed by Spring
==> Preparing: select name from track_info where trackid = ?
==> Parameters: 1736(Integer)
<== Columns: name
<== Row: 寂寞的人伤心的歌
<== Total: 1
Committing JDBC Connection [HikariProxyConnection@39512118 wrapping com.mysql.cj.jdbc.ConnectionImpl@7ba30dd3]
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@66d01651]
有事务时打印:
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@26641092]
JDBC Connection [HikariProxyConnection@1041118964 wrapping com.mysql.cj.jdbc.ConnectionImpl@787bb045] will be managed by Spring
==> Preparing: update track_info set statusid = ? ,modifydate=now() where trackid in ( ? )
==> Parameters: 402(Integer), 1736(Integer)
<== Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@26641092]
Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@26641092] from current transaction
我的最终实现是:
1在启动类上增加,这里加了PlatformTransactionManager 自定义bean
2 在service实现方法上加注解@Transactional,并且这个方法不能throws exception,否则事务失效
3 pom.xml中不引入jdbc,或者jpa的依赖包
4 在数据源配置xml中不再指定事务
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
@SpringBootApplication
@EnableTransactionManagement
@EnableScheduling
public class Application {
// 其中 dataSource 框架会自动为我们注入
@Bean
public PlatformTransactionManager txManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}