2010-10-29 13 views
12

मैं सफलता के बिना स्प्रिंग-टेस्ट का उपयोग करते समय जेडीबीसी लेनदेन रोलबैक प्राप्त करने की कोशिश कर रहा हूं। जब मैं निम्नलिखित चलाता हूं तो SQL अद्यतन हमेशा प्रतिबद्ध होता है।वसंत जेडीबीसी परीक्षणों पर लेनदेन रोलबैक

package my.dao.impl; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.test.annotation.Rollback; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.TestExecutionListeners; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; 
import org.springframework.test.context.transaction.TransactionConfiguration; 

import javax.sql.DataSource; 
import java.sql.Connection; 
import java.sql.Statement; 

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class}) 
@ContextConfiguration(locations={"classpath:ApplicationContext-test-DAOs.xml"}) 
@TransactionConfiguration(defaultRollback = true) 
public class ConfirmationMatchingDAOImplTest { 

    @Autowired 
    private DataSource dataSource; 

    @Test 
    public void shouldInsertSomething() throws Exception { 
     final Connection connection = dataSource.getConnection(); 
     final Statement statement = connection.createStatement(); 
     statement.executeUpdate("insert into TEST_INSERT values (1, 'hello')"); 
     statement.close(); 
     connection.close(); 
    } 
} 

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/> 
    <property name="url" value="jdbc:sqlserver://makeitfunky:1490;databaseName=fonzie"/> 
    <property name="username" value="ralph"/> 
    <property name="password" value="p0n1es_R_kew1"/> 
</bean> 

क्या मैं गलत कर रहा हूँ?

इसके अतिरिक्त, क्या मैं बहुत सी टिप्पणियों का उपयोग कर रहा हूं? क्या मैं इसे थोड़ा क्लीनर बना सकता हूं?

उत्तर

16

आप स्पष्ट रूप से @TestExecutionListeners एनोटेशन का उपयोग कर परीक्षा निष्पादन श्रोताओं कॉन्फ़िगर नहीं करते हैं, स्प्रिंग डिफ़ॉल्ट DependencyInjectionTestExecutionListener, DirtiesContextTestExecutionListener, और TransactionalTestExecutionListener द्वारा कॉन्फ़िगर करता है। TransactionalTestExecutionListener डिफ़ॉल्ट रोलबैक अर्थशास्त्र के साथ लेनदेन परीक्षण निष्पादन प्रदान करता है। श्रोताओं की सूची से @TestExecutionListeners स्पष्ट रूप से घोषित करके और श्रोताओं की सूची से TransactionalTestExecutionListener छोड़कर, आप लेनदेन संबंधी सहायता अक्षम कर रहे हैं।

आपको कक्षा या विधि स्तर पर @Transactional एनोटेशन भी जोड़ना होगा।

आपको DataSourceTransactionManager द्वारा प्रबंधित लेन-देन कनेक्शन प्राप्त करने के लिए DataSourceUtils का भी उपयोग करना होगा।

+0

मैंने @TestExecutionListeners को हटा दिया और @Transactional जोड़ा। तब मुझे ऐप-कॉन्टेक्ट (डेटासोर्सट्रांसक्शन मैनेजर) में एक लेनदेन प्रबंधक बीन जोड़ना पड़ा। टीएक्सएन वापस लुढ़का नहीं गया था इसलिए मैंने @ ट्रान्सएक्शन कॉन्फ़िगरेशन (डिफ़ॉल्ट रोलबैक = सत्य) जोड़ा। टीएक्सएन अभी भी वापस लुढ़का नहीं गया था इसलिए मैंने परीक्षण विधि में @ रोलबैक जोड़ा। केवल तभी मैंने स्प्रिंग लॉग देखा कि यह टीएक्सएन वापस रोल कर रहा था, लेकिन अपडेट अभी भी डीबी पर जारी है। एसक्यूएल सर्वर और उसके ड्राइवर के साथ कुछ करने के लिए शायद? – Synesso

+1

जोड़ा गया डेटा स्रोत मेरे जवाब में उपयोग करता है। –

+0

आह, मुझे आपकी आखिरी टिप्पणी के बारे में अधिसूचित नहीं किया गया था। इस बीच मैंने अपने संदर्भ को एक TransactionAwareDataSourceProxy में डेटास्रोत को लपेटने के लिए बदल दिया है। वह काम किया। तो वहां आप एक ही काम करने के दो तरीके जाते हैं। अब यह देखने के लिए कि इनमें से कौन सी एनोटेशन मैं छुटकारा पा सकता हूं और अभी भी काम कर रहा हूं। – Synesso

1

ऐसा इसलिए हो सकता है क्योंकि आपके पास परीक्षण विधि के लिए @Transactional नहीं है?

+1

मैं @Transactional जोड़ा गया है और इसका कोई प्रभाव नहीं पड़ा। मैंने @ रोलबैक भी जोड़ा और इसका अभी भी कोई प्रभाव नहीं पड़ा। – Synesso

0

वसंत में @Transactional एनोटेशन का उपयोग करते समय, आप अपने स्प्रिंग विन्यास फ़ाइल में निम्न पंक्ति जोड़ना होगा:

<tx:annotation-driven transaction-manager="transactionManager"/> 

लेन-देन-प्रबंधक संपत्ति लेनदेन प्रबंधक सेम में परिभाषित के लिए एक संदर्भ रखती है वसंत विन्यास फाइल। लेनदेन इंटरसेप्टर को लागू करते समय यह कोड वसंत को @ ट्रान्सएक्शन एनोटेशन का उपयोग करने के लिए कहता है। इसके बिना, @ ट्रांसेक्शनल एनोटेशन को नजरअंदाज कर दिया जाता है, जिसके परिणामस्वरूप आपके कोड में कोई लेनदेन नहीं होता है।

Source on IBM website

+1

मुझे याद नहीं है कि वास्तव में समस्या क्या थी, लेकिन अतिरिक्त जानकारी के लिए धन्यवाद। – Synesso

0

अतिरिक्त जानकारियां:

इस लाइन

<tx:annotation-driven transaction-manager="transactionManager"/> 

transaction-manager विशेषता का डिफ़ॉल्ट मान "transactionManager" है के लिए

। यह विशेषता केवल तभी जरूरी है जब लेनदेन का बीन आईडी/नाम प्रबंधक 'लेनदेन प्रबंधक' नहीं है।

<tx:annotation-driven /> 
0

आप श्रेणी स्तर पर @Transactional जोड़ने की जरूरत: तो आप बस सेट करना होगा। कुछ इस तरह:

@TransactionConfiguration(transactionManager = "txManager",defaultRollback = true) 
@Transactional 

यहाँ txManager एक उदाहरण या सेम application context से लेन-देन प्रबंधक की आईडी है।

<!-- Transaction Manager --> 
    <bean id="txManager" 
      class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="sessionFactory" /> 
    </bean> 

    <tx:annotation-driven transaction-manager="txManager" /> 
2

आप के बारे में संस्करण 3,1

@Transactional 
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = {TestDbConfig.class, SomeService.class}) 
public class SomeTest { 

@Inject 
private SomeService someService; 

@PersistenceContext 
private EntityManager em; 

@Test 
public void someTest() {} 

के बाद से गैर एक्सएमएल विधि इस अच्छी तरह से काम करता है उपयोग कर रहे हैं परीक्षण config तो यह रूप लेता है। नोटिस @EnableTransaction प्रबंधन और तथ्य यह है कि आप वैश्विक परीक्षण डिफ़ॉल्ट रोलबैक घोषित कर सकते हैं। यह एक बड़ी परियोजनाओं पर विशेष रूप से उपयोगी हो जाता है।

@Configuration 
@PropertySource(value = "classpath:app.properties") 
@EnableTransactionManagement 
@TransactionConfiguration(defaultRollback = true) 
public class TestDbConfig { 

//read the parameters from properties 
@Value("${hibernate.dialect:unset}") 
private String hibernateDialect; 

@Bean 
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { 
    return new PropertySourcesPlaceholderConfigurer(); 
} 

@Bean 
public PlatformTransactionManager transactionManager() { 
    //for example 
    JpaTransactionManager transactionManager = new JpaTransactionManager(); 
    transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject()); 
    return transactionManager; 
} 

@Bean 
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() { 
    //set the datasource 
    //set the JpaVendorAdapter 
    //set the packagesToScan 
    return some sort of LocalContainerEntityManagerFactoryBean; 
} 

@Bean 
DataSource dataSource() { 
    return dataSource from jndi or a DriverManagerDataSource(); 
} 

}

2

इस टिप्पणी जोड़ने, और कोई रोल वापस परीक्षण मामलों में होगा:

@TransactionConfiguration(defaultRollback=false) 

मेरे एनोटेशन इस तरह दिखता है:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "/../applicationContext.xml" }) 
@TransactionConfiguration(defaultRollback=true) 
public class DBCreatorTest { 
संबंधित मुद्दे