Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Design and Architecture
  4. Database transaction boundaries in three tier

Database transaction boundaries in three tier

Scheduled Pinned Locked Moved Design and Architecture
questioncsharpdatabasehelp
7 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    AliasElias
    wrote on last edited by
    #1

    Consider the following simplified case where I store several users at once. Transaction trans = cn.begintrans foreach (name in nameArray) { Person p = new Person(name); Person.Insert() } trans.commit(); I want Person.Insert() to: - Use the transaction created. (I can't access the transaction object inside the insert() call) This way, the users are not created when the BL produces an error. - Still make it reusable in a non transactonal context (such as creating a single user) I could do it with a using statment using a transactionscope instead, but actually I am wondering how it was done before .NET 2.0? How can I make the insert method available in transactional and none transactional context without violating three tier principles?

    J C H 3 Replies Last reply
    0
    • A AliasElias

      Consider the following simplified case where I store several users at once. Transaction trans = cn.begintrans foreach (name in nameArray) { Person p = new Person(name); Person.Insert() } trans.commit(); I want Person.Insert() to: - Use the transaction created. (I can't access the transaction object inside the insert() call) This way, the users are not created when the BL produces an error. - Still make it reusable in a non transactonal context (such as creating a single user) I could do it with a using statment using a transactionscope instead, but actually I am wondering how it was done before .NET 2.0? How can I make the insert method available in transactional and none transactional context without violating three tier principles?

      J Offline
      J Offline
      Joe DiNatale
      wrote on last edited by
      #2

      I would just overload the insert() method so that, if you pass in a transaction object, it uses it.

      A 1 Reply Last reply
      0
      • J Joe DiNatale

        I would just overload the insert() method so that, if you pass in a transaction object, it uses it.

        A Offline
        A Offline
        AliasElias
        wrote on last edited by
        #3

        That is an option, but ultimately I'm looking for a way to create business logic methods which are reusable in other BL methods in a transactional context without too much hassle. Writing two versions of each method (one with transactional support and one without) seems hard to maintain. I find it weird that only "recently" (using transactionscope) this is possible without repetitive code.

        1 Reply Last reply
        0
        • A AliasElias

          Consider the following simplified case where I store several users at once. Transaction trans = cn.begintrans foreach (name in nameArray) { Person p = new Person(name); Person.Insert() } trans.commit(); I want Person.Insert() to: - Use the transaction created. (I can't access the transaction object inside the insert() call) This way, the users are not created when the BL produces an error. - Still make it reusable in a non transactonal context (such as creating a single user) I could do it with a using statment using a transactionscope instead, but actually I am wondering how it was done before .NET 2.0? How can I make the insert method available in transactional and none transactional context without violating three tier principles?

          C Offline
          C Offline
          CodingYoshi
          wrote on last edited by
          #4

          You just created a Person object inside the foreach loop after starting a transaction. Why should the person know about the transaction if you are not providing it? Joe is right below, somehow you have to make the person aware of the transaction. In other words, how is that instantiation any different than if you did it before beginning transaction? How is this a three tier architecture?

          A 1 Reply Last reply
          0
          • C CodingYoshi

            You just created a Person object inside the foreach loop after starting a transaction. Why should the person know about the transaction if you are not providing it? Joe is right below, somehow you have to make the person aware of the transaction. In other words, how is that instantiation any different than if you did it before beginning transaction? How is this a three tier architecture?

            A Offline
            A Offline
            AliasElias
            wrote on last edited by
            #5

            Thank you for your reply. The sample I provided serves as an example a for what I'm trying to achieve, I don't consider it "correct". You are right about the sample not being three tier also. I'm only looking for a way to make a method reusable in both a transactional and a non transactional context (such as insertPerson) without writing two versions of it...if that is possible? You might write this method just to insert a person into the db and later on you notice that you need to reuse this method in a transaction elsewhere in your application. (for example to insert multiple persons at once) That would basicly mean you need to completely rewrite this method using a transaction for this purpose only. On the other hand, you can use a transactionscope in .NET which automatically attaches the active transaction to any ADO.NET database call. This way you don't have to rewrite to insertPerson method to be used in transactions. I'm just wondering what others do in such a situation? Rewrite any method they need to reuse in a transaction with another method signature (e.g. adding a transaction argument like you said.)...that just seems a bit redundant to me.

            C 1 Reply Last reply
            0
            • A AliasElias

              Thank you for your reply. The sample I provided serves as an example a for what I'm trying to achieve, I don't consider it "correct". You are right about the sample not being three tier also. I'm only looking for a way to make a method reusable in both a transactional and a non transactional context (such as insertPerson) without writing two versions of it...if that is possible? You might write this method just to insert a person into the db and later on you notice that you need to reuse this method in a transaction elsewhere in your application. (for example to insert multiple persons at once) That would basicly mean you need to completely rewrite this method using a transaction for this purpose only. On the other hand, you can use a transactionscope in .NET which automatically attaches the active transaction to any ADO.NET database call. This way you don't have to rewrite to insertPerson method to be used in transactions. I'm just wondering what others do in such a situation? Rewrite any method they need to reuse in a transaction with another method signature (e.g. adding a transaction argument like you said.)...that just seems a bit redundant to me.

              C Offline
              C Offline
              CodingYoshi
              wrote on last edited by
              #6

              Here is what I would do in such a case: Person class will have a method called Save(). When this method is called it will call the DAL's Save method and pass itself in. DAL will ask the person if it should be inserted or updated--no need to create separate methods for update and insert but you can. If it is to be inserted then DAL should call its own private method and insert the person and do the same if update. For multiple persons, I would create a PersonCollection class and when Save() is called it will call the PersonCollectionDAL and pass itself in. The PersonCollectionDAL can either ask each person to Save() and pass a transaction over to it. Make this Save() method internal so it is only accessible from DAL Layer not UI Layer. Alternatively, the PersonCollectionDAL can throw all the persons in a DataTable and ask a dataAdapter to insert them. There is no right and wrong way, it is about software craftsmanship. If you are worried about reusing the insert methods code you mentioned above, then simply make the code a private method and the two public methods (Single and Transactional) can both use it. Obviously, this is just a suggestion and when you start your implementation you will have other obstacles to overcome. Finally, although transactions can be used to speed things up for multiple inserts, yet I do not like using them because if one person is not inserted then why should the other ones roll back. Transactions are supposed to be for steps which depend on each other and either all pass or all fail. It is pretty obvious that is not the case here.

              1 Reply Last reply
              0
              • A AliasElias

                Consider the following simplified case where I store several users at once. Transaction trans = cn.begintrans foreach (name in nameArray) { Person p = new Person(name); Person.Insert() } trans.commit(); I want Person.Insert() to: - Use the transaction created. (I can't access the transaction object inside the insert() call) This way, the users are not created when the BL produces an error. - Still make it reusable in a non transactonal context (such as creating a single user) I could do it with a using statment using a transactionscope instead, but actually I am wondering how it was done before .NET 2.0? How can I make the insert method available in transactional and none transactional context without violating three tier principles?

                H Offline
                H Offline
                Hesham Amin
                wrote on last edited by
                #7

                I think using TransactionScope Class[^] will solve most of your problems.

                Hesham A. Amin My blog

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups