Java @当@Autowired应用时,事务性不起作用
我已经编写了一个示例应用程序来测试Spring中带注释的事务管理(@Transactional) 上下文文件Java @当@Autowired应用时,事务性不起作用,java,spring,transactions,Java,Spring,Transactions,我已经编写了一个示例应用程序来测试Spring中带注释的事务管理(@Transactional) 上下文文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springfr
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
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.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<tx:annotation-driven />
<context:component-scan base-package="com.test" />
<bean id="playerService" class="com.test.service.PlayerServiceImpl" />
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dbUtil" class="com.test.util.DbUtil" init-method="initialize">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<context:property-placeholder location="jdbc.properties"/>
PlayerDaoImpl的实现
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.test.model.Player;
import com.test.model.Team;
@Repository
public class PlayerDaoImpl implements PlayerDao{
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Transactional (propagation=Propagation.REQUIRED)
public void insertPlayer(Player player){
String insertSql ="INSERT INTO PLAYERS (PLAYER_NAME, DOB, AGE, TEAM_ID) VALUES(?,?,?,?);";
jdbcTemplate.update(insertSql,new Object[]{player.getPlayerName(),player.getDob(), player.getAge(), player.getTeamId()});
}
@Transactional (propagation=Propagation.REQUIRED)
public void insertTeam(Team team){
String insertSql ="INSERT INTO TEAMS (TEAM_ID, TEAM_NAME) VALUES(?,?);";
jdbcTemplate.update(insertSql,new Object[]{team.getTeamId(),team.getTeamName()});
}
}
玩家服务
import com.test.model.Team;
public interface PlayerService {
public void createTeam1(Team team) throws Exception;
public void createTeam2(Team team) throws Exception;
}
PlayerService实现
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.test.model.Team;
import com.test.persistence.PlayerDao;
@Service
public class PlayerServiceImpl implements PlayerService{
@Autowired
private PlayerDao playerDao;
public void createTeam1(Team team) throws Exception{
playerDao.insertPlayer(team.getPlayers().get(0));
playerDao.insertPlayer(team.getPlayers().get(1));
playerDao.insertPlayer(team.getPlayers().get(2));
playerDao.insertTeam(team);
}
public void createTeam2(Team team) throws Exception{
playerDao.insertPlayer(team.getPlayers().get(0));
playerDao.insertPlayer(team.getPlayers().get(1));
playerDao.insertTeam(team);
throw new Exception();
}
}
主要班级
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.test.model.Player;
import com.test.model.Team;
import com.test.service.PlayerService;
public class TestMain {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
PlayerService playerService = (PlayerService) context.getBean("playerService");
Team t1 = new Team();
t1.setTeamId(1);
t1.setTeamName("Team-1");
Player p1 = new Player("Player 1", LocalDate.of(1981,05,02), 1);
Player p2 = new Player("Player 2", LocalDate.of(1983,02,15), 1);
Player p3 = new Player("Player 3", LocalDate.of(1980,12,31), 1);
List<Player> players1 = new ArrayList<Player>();
players1.add(p1);
players1.add(p2);
players1.add(p3);
t1.setPlayers(players1);
Team t2 = new Team();
t2.setTeamId(2);
t2.setTeamName("Team-2");
Player p4 = new Player("Player 4", LocalDate.of(1989,05,02), 1);
Player p5 = new Player("Player 5", null, 1);
List<Player> players2 = new ArrayList<Player>();
players2.add(p4);
players2.add(p5);
t2.setPlayers(players2);
try {
playerService.createTeam1(t1);
playerService.createTeam2(t2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
import java.time.LocalDate;
导入java.util.ArrayList;
导入java.util.List;
导入org.springframework.context.ApplicationContext;
导入org.springframework.context.support.ClassPathXmlApplicationContext;
导入com.test.model.Player;
导入com.test.model.Team;
导入com.test.service.PlayerService;
公共类TestMain{
公共静态void main(字符串[]args){
ApplicationContext上下文=新的ClassPathXmlApplicationContext(“spring config.xml”);
PlayerService PlayerService=(PlayerService)context.getBean(“PlayerService”);
团队t1=新团队();
t1.1(1);
t1.团队名称(“团队1”);
玩家p1=新玩家(“玩家1”,LocalDate.of(1981,05,02),1);
玩家p2=新玩家(“玩家2”,LocalDate.of(1983,02,15),1);
玩家p3=新玩家(“玩家3”,LocalDate.of(1980,12,31),1);
List players1=新的ArrayList();
玩家1。添加(p1);
玩家1。添加(p2);
玩家1.添加(p3);
t1.赛特球员(球员1);
团队t2=新团队();
t2.2(2);
t2.Settamname(“第二团队”);
玩家p4=新玩家(“玩家4”,LocalDate.of(1989,05,02),1);
玩家p5=新玩家(“玩家5”,空,1);
List players2=新的ArrayList();
玩家2.添加(p4);
玩家2.添加(p5);
t2.赛特球员(球员2);
试一试{
playerService.createTeam1(t1);
playerService.createTeam2(t2);
}捕获(例外e){
e、 printStackTrace();
}
}
}
当我将playerDao设置为上下文文件中PlayerService的属性之一时,事务运行良好,如下所示(playerDao没有@Autowired set)
但是,当I@Autowired playerDao连接到PlayerServiceImpl类时,事务不适用(事务不起作用)
我在这里犯了什么错误?这个示例应用程序将使用注释演示Spring事务。PlayerServiceImpl类中的createTeam1()方法将创建3名玩家和一个团队。因此,一旦完成运行,它将在PLAYERS表中创建3行,在TEAMS表中创建一行。createTeam2()方法试图创建两个玩家和一个团队。在这个方法的末尾,它抛出一个异常,该异常应该回滚玩家和团队创建,并且不能在玩家和团队表中创建行 对于PlayerServiceImpl类中的PlayerDao,使用@Autowired注释是正确的。然而,申请交易是不正确的。@M.Deinum清楚地解释了当前代码通过直接在DAO方法(在本例中为insertPlayer()和insertTeam()方法)中应用事务来创建7个单独的事务。因此,应用事务的正确方法是在服务方法(本例中为createTeam1()和createTeam2()方法)上 为了在引发异常时回滚事务,必须使用正确的异常(作为@Transactional注释的属性)设置rollbackfor transaction属性。然后,spring事务在抛出异常时回滚更改。因此,正确的服务方法实现如下:
@Transactional (propagation=Propagation.REQUIRED, rollbackFor = {Exception.class})
public void createTeam1(Team team) throws Exception{
playerDao.insertPlayer(team.getPlayers().get(0));
playerDao.insertPlayer(team.getPlayers().get(1));
playerDao.insertPlayer(team.getPlayers().get(2));
playerDao.insertTeam(team);
}
@Transactional (propagation=Propagation.REQUIRED, rollbackFor = {Exception.class})
public void createTeam2(Team team) throws Exception{
playerDao.insertPlayer(team.getPlayers().get(0));
playerDao.insertPlayer(team.getPlayers().get(1));
playerDao.insertTeam(team);
throw new Exception();
}
您的事务应该从服务级别开始,它只从Dao开始。将服务标记为
@Tansactional
将@Transactional添加到服务级别的具体原因是什么?是否正在创建团队和玩家原子操作<当事务在DAO中启动和完成时,服务方法中的代码>抛出新异常(),不会导致回滚。顺便问一下,“交易不起作用”是什么意思?数据库中是否有异常或无数据?您的服务方法是事务边界,而不是对存储库的单个调用。现在您有7个单独的事务(4个用于createTeam1,3个用于createTeam2)。因此,实际上,@Autowired
的行为是预期的行为。感谢@M.Deinum的解释。我非常感谢你的解释。
<bean id="playerService" class="com.slpl.service.PlayerServiceImpl" >
<property name="playerDao" ref="playerDao" />
</bean>
<bean id="playerDao" class="com.slpl.persistence.PlayerDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
@Transactional (propagation=Propagation.REQUIRED, rollbackFor = {Exception.class})
public void createTeam1(Team team) throws Exception{
playerDao.insertPlayer(team.getPlayers().get(0));
playerDao.insertPlayer(team.getPlayers().get(1));
playerDao.insertPlayer(team.getPlayers().get(2));
playerDao.insertTeam(team);
}
@Transactional (propagation=Propagation.REQUIRED, rollbackFor = {Exception.class})
public void createTeam2(Team team) throws Exception{
playerDao.insertPlayer(team.getPlayers().get(0));
playerDao.insertPlayer(team.getPlayers().get(1));
playerDao.insertTeam(team);
throw new Exception();
}