এনটোটেশন @ ট্রান্সজেকশনাল। কীভাবে রোলব্যাক করবেন?


91

আমি এই টিকাটি কোনও দাও শ্রেণীর জন্য সফলভাবে ব্যবহার করেছি। এবং রোলব্যাক পরীক্ষার জন্য কাজ করে।

তবে এখন আমার কেবল পরীক্ষাগুলি নয়, রিয়েল কোড রোলব্যাক করা দরকার। পরীক্ষাগুলিতে ব্যবহারের জন্য বিশেষ টিকা রয়েছে। কিন্তু কোন টীকা নন-টেস্ট কোডের জন্য? এটা আমার কাছে বড় প্রশ্ন। আমি এর জন্য ইতিমধ্যে একটি দিন কাটিয়েছি। অফিসিয়াল ডকুমেন্টেশন আমার প্রয়োজনীয়তা পূরণ করে নি।

class MyClass { // this does not make rollback! And record appears in DB.
        EmployeeDaoInterface employeeDao;

        public MyClass() {
            ApplicationContext context = new ClassPathXmlApplicationContext(
                    new String[] { "HibernateDaoBeans.xml" });
            employeeDao = (IEmployeeDao) context.getBean("employeeDao");
         }

        @Transactional(rollbackFor={Exception.class})
    public void doInsert( Employee newEmp ) throws Exception {
        employeeDao.insertEmployee(newEmp);
        throw new RuntimeException();
    }
}

কর্মচারী দাও

@Transactional
public class EmployeeDao implements IEmployeeDao {
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public void insertEmployee(Employee emp) {
        sessionFactory.getCurrentSession().save(emp);
    }
}

এবং এখানে একটি পরীক্ষা দেওয়া হয়েছে যার জন্য টীকাগুলি ভালভাবে কাজ করে:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/HibernateDaoBeans.xml" })
@TransactionConfiguration(transactionManager = "txManager", defaultRollback = true)
@Transactional
public class EmployeeDaoTest {

    @Autowired
    EmployeeDaoInterface empDao;

    @Test
    public void insert_record() {
       ...
       assertTrue(empDao.insertEmployee(newEmp));
    }

হাইবারনেটডাওবিন্স.এক্সএমএল

   ...
<bean id="employeeDao" class="Hibernate.EmployeeDao">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>
    <tx:annotation-driven transaction-manager="txManager"/>

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



** হ্যাঁ, আমি লেনদেনটি ফিরিয়ে দিয়েছি। আমি কেবল পরিষেবাটির জন্য বিয়ান যোগ করেছি ... এবং তারপরে এনটোটেশন @ ট্রানজেকশনাল কাজ শুরু করুন :-) **

<bean id="service" class="main.MyClass">
    <property name="employeeDao" ref="employeeDao" />
</bean>

সবাইকে ধন্যবাদ, রাশিয়া আপনাকে ভুলবে না!

উত্তর:


163

RuntimeExceptionচিহ্নিত হিসাবে চিহ্নিত পদ্ধতি থেকে যে কোনওটি নিক্ষেপ করুন @Transactional

ডিফল্টরূপে সমস্ত RuntimeExceptionরোলব্যাক লেনদেন যেখানে চেক ব্যতিক্রমগুলি হয় না। এটি একটি ইজেবি উত্তরাধিকার। ব্যবহার করে আপনি এই কনফিগার করতে পারেন rollbackFor()এবং noRollbackFor()টীকা প্যারামিটার:

@Transactional(rollbackFor=Exception.class)

এটি কোনও ব্যতিক্রম ছোঁড়ার পরে রোলব্যাক লেনদেন করবে ।


4
আমি এটা চেষ্টা করেছি. এটা কাজ করে না! আমি রোলব্যাক অপারেশন সম্পর্কে সরাসরি দাও অবজেক্টে বলি না, এটি হতে পারে। আমি অন্য একটি অবজেক্ট সম্পর্কে বলি যা দাও পদ্ধতিতে কল ব্যবহারের ক্রম ব্যবহার করে যা @ ট্রান্সজেকশনাল ব্যবহার করে। এবং আমি আমার ক্লাসের জন্য একই টীকা যুক্ত করার চেষ্টা করি যা এই দাওটিকে ডাকে। তবে এটি এখানে কাজ করে না।
মস্কো বয়

4
এটি সত্যিই এইভাবে কাজ করে :-)। আপনার যদি বেশ কয়েকটি ডিএও'র কাছে কল করার কোনও পরিষেবা থাকে তবে সেবারও একটি @Transactionalটিকা থাকা দরকার। অন্যথায় প্রতিটি ডিএও কল আপনি পরিষেবাটিতে একটি ব্যতিক্রম ছুঁড়ে ফেলার আগেই শুরু করে এবং নতুন লেনদেনের প্রতিশ্রুতি দেয়। নীচের লাইনটি হ'ল: ব্যতিক্রমটিকে অবশ্যই চিহ্নিত পদ্ধতি (পলায়ন) ছেড়ে যেতে হবে @Transactional
টমাসজ নুরকিউইচ

প্রথম পোস্টে যুক্ত কোডটি দেখুন। আমার কাছে কোডের কিছু অংশ রয়েছে। মৃত্যুদণ্ড কার্যকর হওয়ার পরে আমার কাছে ডিবিতে রেকর্ড রয়েছে। => রোলব্যাক এখনও কাজ করে না।
মস্কো বয়

ডিএও থেকে ব্যতিক্রম ছুঁড়ে দেওয়াও কি লেনদেনকে পিছিয়ে দেয় না? আপনি কি org.springframework.orm.hibernate3.HibernateTransactionManagerআপনার বসন্ত প্রসঙ্গে কনফিগার করেছেন? আপনি যদি org.springframework.transactionলগার সক্ষম করেন তবে এটি কি আকর্ষণীয় কিছু দেখায়?
টমাসজ নুরকিউইচজ

4
যদি আপনি স্প্রিং বুট ব্যবহার করেন এবং এটি ডেটাসোর্সটিকে স্বয়ংক্রিয়ভাবে কনফিগার করতে দিন তবে এটি হিকারিডাটাসোর্স ব্যবহার করবে যার ডিফল্টরূপে স্বয়ংক্রিয় প্রতিশ্রুতি সত্য হিসাবে সেট করা আছে। আপনাকে এটি মিথ্যাতে সেট করতে হবে: হিকারিডাটাসোর্স.সেটআউটো কমিট (মিথ্যা); ডেটাসোর্সট্রান্সটিম্যানেজার শিমটি কনফিগার করার সময় আমি @ কনফিগারেশন ক্লাসে এই পরিবর্তনটি করেছি।
অ্যালেক্স

83

বা প্রোগ্রামক্রমে

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

12
হ্যাঁ. কারণ কখনও কখনও আপনার ত্রুটি না ছড়িয়ে রোলব্যাক করা দরকার।
এরিকা কেন

4
তুমি একজন জীবন রক্ষাকারী.
ওয়ালগুলি

রোলব্যাক ইমো চালানোর জন্য এটি আরও উপযুক্ত উপায়, আদর্শভাবে আপনি পরিচিত বা নিয়ন্ত্রিত অবস্থার জন্য ব্যতিক্রম ছুঁড়ে দিতে চান না।
জলপিনো

4
কখনও কখনও এটি কাজ করে না। উদাহরণস্বরূপ, আমার ক্ষেত্রে আমার কাছে একটি লেনদেনের পরিষেবা এবং অ-লেনদেনের সংগ্রহস্থল রয়েছে। আমি পরিষেবা থেকে সংগ্রহস্থল কল করি, সুতরাং, এটি পরিষেবা দ্বারা খোলা কোনও লেনদেনে অংশ নেওয়া উচিত। তবে আমি যদি আমার অ-লেনদেনের সংগ্রহস্থল থেকে আপনার কোডটি কল করি তবে এটি লেনদেনের উপস্থিতি সত্ত্বেও NoTransactionException নিক্ষেপ করে।
ভিক্টর ডম্ব্রভস্কি

4
আপনার "অ-লেনদেনের ভাণ্ডার" এ আপনি কোন লেনদেনটি ফিরে যেতে চান?
স্টেফান কে।

5

আপনি যে পদ্ধতিতে ফিরে যেতে চান তা থেকে আপনি একটি চেক করা ব্যতিক্রম নিক্ষেপ করতে পারেন। এটি বসন্তের মধ্যে সনাক্ত করা হবে এবং আপনার লেনদেনটি কেবল রোলব্যাক হিসাবে চিহ্নিত করা হবে।

আমি ধরে নিচ্ছি আপনি এখানে বসন্ত ব্যবহার করছেন। এবং আমি ধরে নিয়েছি যে আপনি যে পরীক্ষাগুলি আপনার পরীক্ষাগুলিতে উল্লেখ করেছেন তা হ'ল বসন্ত পরীক্ষা ভিত্তিক টিকা ot

স্প্রিং ফ্রেমওয়ার্কের লেনদেনের অবকাঠামোকে নির্দেশ করার প্রস্তাবিত উপায়টি হ'ল যে কোনও লেনদেনের কাজটি ফিরিয়ে আনতে হবে তা হ'ল বর্তমানে কোনও লেনদেনের প্রসঙ্গে কার্যকর হওয়া কোড থেকে একটি ব্যতিক্রম ছুঁড়ে ফেলা।

এবং নোট করুন:

দয়া করে নোট করুন যে স্প্রিং ফ্রেমওয়ার্কের লেনদেনের অবকাঠামো কোডটি ডিফল্টরূপে কেবল রানটাইম, চেক না করা ব্যতিক্রমগুলির ক্ষেত্রে রোলব্যাকের জন্য একটি লেনদেনকে চিহ্নিত করবে; এটি হ'ল, যখন নিক্ষিপ্ত ব্যতিক্রমটি রানটাইম এক্সেপশনটির কোনও উদাহরণ বা সাবক্লাস হয়।


1

আমার জন্য রোলব্যাকফোর পর্যাপ্ত ছিল না, তাই আমাকে এটি রাখা হয়েছিল এবং এটি প্রত্যাশার মতো কাজ করে:

@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)

আমি আসা করি এটা সাহায্য করবে :-)


4
না এটি TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();আপনাকে সাহায্য করার নীচে কিছুতেই সহায়তা করে না
এনারসিসিও
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.