Saturday, September 22, 2012

Rails 4 - Transaction isolation level


After long time I am writing small post, as now a days not able manage a time or you can say I am just working ;)

TL;DR - In Rails 4, Jon Leighton has added a support for specifying transaction isolation level. This transaction level we can pass when starting transaction(or you can say while calling transaction method)

Note : This blog post is copied from Jon Leighton commits, which he did in a rails repository

Before continuing reading this post, it will be good if you read about Transaction Isolation over here.

Isolation is a property that defines how/when the changes made by one operation become visible to other concurrent operations. Isolation is one of the ACID (Atomicity, Consistency, Isolation, Durability) properties.

Highlevel of Isolation does affect on Concurrency property of ACID, as it require to use locks or multiversion concurrency control.

Anyways here is a documentation which Jon Leighton has added in rails trank.

If your database supports setting the isolation level for a transaction, you can set it like so:

Post.transaction(isolation: :serializable) do
  # ...
end

Valid isolation levels are:
* `:read_uncommitted`
* `:read_committed`
* `:repeatable_read`
* `:serializable`

You should consult the documentation for your database to understand the semantics of these different levels:

* http://www.postgresql.org/docs/9.1/static/transaction-iso.html
* https://dev.mysql.com/doc/refman/5.0/en/set-transaction.html

An `ActiveRecord::TransactionIsolationError` will be raised if:
* The adapter does not support setting the isolation level
* You are joining an existing open transaction
* You are creating a nested (savepoint) transaction

The mysql, mysql2 and postgresql adapters support setting the transaction isolation level. However, support is disabled for mysql versions below 5, because they are affected by a bug (http://bugs.mysql.com/bug.php?id=39170) which means the isolation level gets persisted outside the transaction.
References :
http://en.wikipedia.org/wiki/Isolation_(database_systems)
http://www.postgresql.org/docs/9.1/static/transaction-iso.html
https://dev.mysql.com/doc/refman/5.0/en/set-transaction.html
https://github.com/rails/rails/commit/392eeecc11a291e406db927a18b75f41b2658253

Sunday, July 1, 2012

bundle install +
tar_input.rb:49:in `initialize': not in gzip format (Zlib::GzipFile::Error)

This is one of the pending post since 6 month, thought it might helpful to some people.

Today on production server our system team found very strange issue with REE and bundler which lead production server was down for 20 min. This issue did not occur on test (Since on test and production have different version of REE)

Issue is as follows,


Issue was new to me, so I started digging into it using the almighty google.

The solution which I found on net was not applicable since we couldn't afford a downtime.

Issue is actually with ruby-enterprise-1.8.7-2010.02. Which is fixed in ruby-enterprise-1.8.7-2011.01 as described in release note.

http://blog.phusion.nl/2011/02/12/ruby-enterprise-edition-1-8-7-2011-01-released/

But we don't have a time to upgrade REE at this point. So I digged into it and found temporary solution described here.

http://stackoverflow.com/questions/2494659/strange-bundler-error-tar-input-rb49in-initialize-not-in-gzip-format-zlib


Basically you have to clear you gem cache either you are use rvm or not. so I have simply deleted content from my gems folder
like,
sudo rm -rf /opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/cache/

And this worked !!!....

Sunday, February 12, 2012

Configure Repository In Redmine

As Rubyist, most of us we use Redmine for Project Management and git for source code management. Written using the Ruby on Rails framework, it is cross-platform and cross-database. Redmine is open source and released under the terms of the GNU General Public License v2 (GPL).

Git is a free & open source, distributed version control system designed to handle everything from small to very large projects with speed and efficiency.

Redmine provides many features out of that is SCM integration (SVN, CVS, Git, Mercurial, Bazaar and Darcs), which I going to explaing you in this blog post.

I am explaning this because, many time we do a code review for team members. Also some time we need to review a perticuler fix done for any bug. At that time it is very difficult to go through a git log.

So it will be great to use to redmine for this, were we can attach a code to feature or bug and even from git log to issue.

Redmine has this great feature, http://www.redmine.org/projects/redmine/wiki/RedmineRepositories#Repository-user-mapping

Now if we have already git server then, then their are two solution available,

  1. Make git server to support http protocol
  2. Replicate git server on Redmine server it self

both above option are very easy but issue in second option. Issue if you have git server which is runnning separately. Which happens in my case.

Our git server is only accessisble via git protocol like

git clone user_name@repository_server:path_to_project.git

Our git server is used by more than 30 developers were more than 13 repositories get accessed. So I don't want to distrub the development process. So I have decided to replicate git server on redmine.

A. Replicate git server to be used by Redmine

  1. Login to your Redmine server from console
  2. Clone the repository with following command
  # change to your respective user 
 $ su - name_of_user   
  
  # Create a folder to hold your repository
 $ mkdir /any/path/to/create/repo
 
  # change directory
 $ cd /any/path/to/create/repo
 
 # Make a bare clone of the repo
 $ git clone --bare ssh://git@reposerver/usr/local/git_root/foo-project.git
 
  # Switch to repository
 $ cd foo-project.git
 
  # add orignal repository in newly created repository for fetching changes done in orignal repository 
 $ git remote add origin ssh://git@reposerver/usr/local/git_root/foo-project.git
 
  # Above command will feches commit from origanl repo
 $ git fetch origin
 $ git reset --soft refs/remotes/origin/master

  #Make sure bypass the password prompt using ssh config for following command to work from crontab.
 
  # Add the following to your crontab
 */10 * * * * cd /var/local/git_copies/foo-project.git && git fetch origin && git reset --soft refs/remotes/origin/master > /dev/null

Using above command we have setuped a replica of git server on redmine server.

B. Add project repository in Redmine

Go to the redmine, select your project and add repository local path. Goto => setting => repository

C. Fetch commits into redmine

When you first browse the repository, Redmine retrieves the description of all of the existing commits and stores them in the database.
This is done only once per repository but can take a very long time (or even time out) if your repository has hundreds of commits.

To avoid this, you can do it offline.
Run the following rake command on redmine server:

$ ruby script/runner "Repository.fetch_changesets" -e production

All commits will be retrieved in to the Redmine database.

Since Redmdine 0.9.x, you can use following link of your redmine to execute fetch_changesets for a specific project, or all.
http://redmine.example.com/sys/fetch_changesets (=> fetches changesets for all active projects)
http://redmine.example.com/sys/fetch_changesets?id=foo (=> fetches changesets for project foo only)

Now we have sucessfully configured git reposiroty in Redmine.

Now you can use following link for linking revision and commits to issue and vice-varsa.
http://www.redmine.org/projects/redmine/wiki/RedmineTextFormatting