gpt4 book ai didi

java - Spring 交易问题

转载 作者:行者123 更新时间:2023-11-29 06:04:03 25 4
gpt4 key购买 nike

我在使用 Spring 事务时遇到问题。我真的需要帮助,因为我无法弄清楚为什么 personsDao2 没有按应有的方式回滚(请参阅下面用“失败!”评论的断言)。有什么意见吗?

我的 Eclipse 项目可以在 http://www52.zippyshare.com/v/4142091/file.html 下载.所有依赖项都在那里,因此很容易开始。

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.google.common.collect.Lists;

public class MyInnerClass {
private PersonsDao personsDao;

public MyInnerClass() {
}

public PersonsDao getPersonsDao() {
return personsDao;
}

public void setPersonsDao(PersonsDao personsDao) {
this.personsDao = personsDao;
}

@Transactional(propagation = Propagation.REQUIRES_NEW, noRollbackFor = Exception.class)
public void method() {
personsDao.createPersons(Lists.newArrayList(new Person("Eva")));
}
}

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.google.common.collect.Lists;

public class MyOuterClass {
private MyInnerClass myInnerClass;
private PersonsDao personsDao;

public MyInnerClass getMyInnerClass() {
return myInnerClass;
}

public void setMyInnerClass(MyInnerClass myInnerClass) {
this.myInnerClass = myInnerClass;
}

public void setMyInnerClass() {
}

public PersonsDao getPersonsDao() {
return personsDao;
}

public void setPersonsDao(PersonsDao personsDao) {
this.personsDao = personsDao;
}

public MyOuterClass() {
}

@Transactional(propagation = Propagation.REQUIRED, rollbackFor=Exception.class)
public void method() {
try {
personsDao.createPersons(Lists.newArrayList(new Person("Adam")));
throw new RuntimeException("Forced rollback");
} finally {
myInnerClass.method();
}
}
}

public class Person {
public Person(String name) {
this.name = name;
}

public String getName() {
return name;
}

@Override
public String toString() {
return "Customer [name=" + name + "]";
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}

private String name;
}

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;

public class PersonsDao {
public PersonsDao(DataSource dataSource, String tableName) {
namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
this.tableName = tableName;
}

public List<Person> getPersons() {
Map<String, Object> namedParameters = new HashMap<String, Object>();
String getCustomers = "SELECT name FROM " + tableName + " ORDER BY name ASC";
return namedParameterJdbcTemplate.query(getCustomers, namedParameters, getRowMapper());
}

public void createPersons(List<Person> customers) {
SqlParameterSource[] params = SqlParameterSourceUtils.createBatch(customers.toArray());
String createCustomer = "INSERT INTO " + tableName + " VALUES(:name)";
namedParameterJdbcTemplate.batchUpdate(createCustomer, params);
}

public void deleteCustomers() {
Map<String, Object> namedParameters = new HashMap<String, Object>();
String deleteCustomers = "DELETE FROM " + tableName;
namedParameterJdbcTemplate.update(deleteCustomers, namedParameters);
}

private static RowMapper<Person> getRowMapper() {
return new RowMapper<Person>() {
@Override
public Person mapRow(ResultSet arg0, int arg1) throws SQLException {
return new Person(arg0.getString("name"));
}
};
}

private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private String tableName;
}

import static org.junit.Assert.*;
import javax.annotation.Resource;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/beans.xml")
@Transactional(rollbackFor = Exception.class)
public class PersonsDaoTest {
@Resource
private MyInnerClass myInnerClass;
@Resource
private MyOuterClass myOuterClass;

@Test(expected = Exception.class)
public void test() {
myOuterClass.method();
fail();
}

@After
public void after() {
assertEquals(1, myInnerClass.getPersonsDao().getPersons().size());
assertEquals(0, myOuterClass.getPersonsDao().getPersons().size());
}

@Before
public void before() {
myInnerClass.getPersonsDao().deleteCustomers();
myOuterClass.getPersonsDao().deleteCustomers();
assertEquals(0, myInnerClass.getPersonsDao().getPersons().size());
assertEquals(0, myOuterClass.getPersonsDao().getPersons().size());
}
}

最佳答案

首先,您的两个类上的@Transactional 注释被忽略,因为您直接实例化这些类(使用new)而不是从spring 中获取实例上下文。

所以事实上,它归结为这段代码:

try {
personDao2.createPerson(); // creates a person in persons2
throw new RuntimeException();
}
finally {
personDao1.createPerson(); // creates a person in person1
}

finally block 总是被执行,即使在 try block 中抛出异常。因此,测试在 person1person2 中创建了一个人。

关于java - Spring 交易问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9139812/

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