当前位置: 首页 > 知识库问答 >
问题:

@Transactional不工作时,@自动安装应用

巴英韶
2023-03-14

我编写了一个示例应用程序来测试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.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"/>

菜豆

import com.test.model.Player;
import com.test.model.Team;

public interface PlayerDao {

public void insertPlayer(Player player);

public void insertTeam(Team team);

}

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();
        }
    }
}

当我在上下文文件中将playerDao设置为PlayerService的属性之一时,事务运行良好,如下所示(playerDao没有@Autowired set);

<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>

但是,当I@Autowired playerDao连接到PlayerServiceImpl类时,事务不适用(事务不起作用)。

我犯了什么错?

共有1个答案

百里泓
2023-03-14

这个示例应用程序将演示使用注释的Spring事务。PlayerServiceImpl类中的createTeam1()方法将创建3名玩家和一个团队。因此,一旦完成运行,它将在PLAYERS表中创建3行,在TEAMS表中创建一行。createTeam2()方法试图创建两个玩家和一个团队。在这个方法的末尾,它抛出一个异常,该异常应该回滚玩家和团队创建,并且不能在玩家和团队表中创建行。

对于PlayerServiceImpl类中的PlayerDao,使用@Autowired注释是正确的。然而,申请交易是不正确的。正如@M.Deinum清楚解释的,当前代码通过直接在DAO方法(在本例中是insertPlayer()和insertTeam()方法)中应用事务来创建7个单独的事务。因此,应用事务的正确方法是在服务方法(本例中为createTeam1()和createTeam2()方法)上。

为了在抛出异常时回滚事务,必须使用正确的异常设置rollbackfor事务属性(作为@Transactional注释的属性)。然后在抛出异常时弹出事务回滚更改。因此,正确的服务方法实现如下;

@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();
}
 类似资料:
  • 我之前有一个关于这个问题的帖子已经解决了。然而,自从用自动连线bean和较少的XML配置重建项目后,我发现我正在重新考虑这个问题。我遵循了我以前的项目实现这一点的方式,但它不起作用。有人能帮助我为什么或者我应该改变什么来使它工作吗? 注册服务: 注册DAO:

  • 我有一个spring webapp,一切都很好,但现在我需要一个事务性方法, 这是我的应用程序上下文。xml 这是我的数据库。xml 在一个服务类中,我有一个autowired属性,这个属性有一个这样的事务方法:我进行更新,将一行值更改为“2”,然后在抛出RuntimeException之后,如果一切正常,则必须回滚更新。 两天前,我尝试了很多可能的解决方案,我在google和stackoverf

  • 我是一个新的springboot和我正在考虑它为一个新的项目。在测试其功能时,我使用@Transactional注释总是失败。 我创建了一个小的MySql数据库,并将其连接到该数据库,设置此application.properties文件: 为什么?

  • 在运行任何自制命令后,我一遍又一遍地出现相同的错误。。。。。。 /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb: 55: in要求从 /usr/local/Library/Homebrew/global.rb: 1: in

  • 我有一个烧瓶Python 3.7应用程序,我想运行在docker和库伯内特斯。 我有以下Docker文件 这个管用(用蟒蛇蛋) 但这不是(但我想坚持这一点) 运行此命令(构建容器后)给出以下错误 但是如上所述,这与以前的Docker文件非常配合。任何帮助都非常感谢。 附加说明: 构建Docker容器时没有错误 这是我的requirements.txt

  • 在尝试了我可以找到的关于这个问题的帖子中提到的所有内容后,我还没有安装psycopg2 警告:MANIFEST_MAKER:找不到标准文件“-C”